import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../di/service_locator.dart';
import '../models/period_model.dart';
import '../utils/errors.dart';
import 'data_service.dart';
import 'period_service.dart';
import 'error_handler.dart';

class AppStateService {

  static final AppStateService _instance = AppStateService._internal();
  
  factory AppStateService() => _instance;
  
  
  final ErrorHandler _errorHandler = get<ErrorHandler>();
  final DataService _dataService = get<DataService>();
  final PeriodService _periodService = get<PeriodService>();
  
  bool _isInitialized = false;
  List<PeriodModel> _periodRecords = [];
  UserProfile? _userProfile;
  bool _isPeriodActive = false;
  CycleInfo? _currentCycleInfo;
  bool _isMinimalistMode = false;
  
  AppStateService._internal();
  
  
  List<PeriodModel> get periodRecords => _periodRecords;
  
  
  bool get isPeriodActive => _isPeriodActive;
  
  
  CycleInfo? get currentCycleInfo => _currentCycleInfo;
  
  
  bool get isInitialized => _isInitialized;
  
  
  UserProfile? getUserProfile() {
    return _userProfile;
  }
  
  
  
  
  
  Future<void> initializeApp() async {
    if (_isInitialized) return;
    
    try {
      
      
      await _dataService.initialize();
      
      
      await _loadData();
      
      
      await _dataService.checkDatabaseStructure();
      
      
      await refreshPredictions();
      
      
      final prefs = await SharedPreferences.getInstance();
      _isMinimalistMode = prefs.getBool('isMinimalistMode') ?? false;
      
      _isInitialized = true;
    } catch (e) {
      final error = AppError(
        message: '初始化应用状态服务失败',
        type: AppErrorType.business
      );
      _errorHandler.handleError(error, 'AppStateService.initializeApp');
      _isInitialized = false;
    }
  }
  
  
  Future<void> _loadData() async {
    try {
      
      final futureResults = await Future.wait<dynamic>([
        _dataService.loadPeriodRecords(),
        _dataService.loadUserProfile(),
        _periodService.getCycleInfo().catchError((e) {
          final error = AppError(message: '加载周期信息失败', type: AppErrorType.business);
          _errorHandler.handleError(error, 'AppStateService._loadData.cycleInfo');
          // 返回一个默认的CycleInfo对象
          return CycleInfo(
            cycleLength: 28,
            periodLength: 5,
            nextPeriodDate: DateTime.now().add(Duration(days: 28)),
            ovulationDate: DateTime.now().add(Duration(days: 14)),
            pregnancyRate: 0.0,
            daysUntilNextPeriod: 28,
            daysUntilOvulation: 14,
            healthScore: 70,
            healthStatus: '良好',
            fertilityWindow: '非受孕窗口期',
            recommendations: ['保持健康作息', '注意营养均衡'],
            predictionConfidence: 50
          );
        })
      ]);

      
      _periodRecords = futureResults[0] as List<PeriodModel>;
      _userProfile = futureResults[1] as UserProfile?;
      _currentCycleInfo = futureResults[2] as CycleInfo?;
      
      
      _isPeriodActive = _checkIfPeriodIsActive();
    } catch (e) {
      final error = AppError(message: '加载数据失败', type: AppErrorType.business);
      _errorHandler.handleError(error, 'AppStateService._loadData');
      
      
      if (e.toString().contains('database is locked')) {
        debugPrint('检测到数据库锁，尝试重新连接...');
        await Future.delayed(const Duration(milliseconds: 100));
        await _dataService.reinitializeDatabase();
        
        
        final futureResults = await Future.wait([
          _dataService.loadPeriodRecords(),
          _dataService.loadUserProfile()
        ]);
        _periodRecords = futureResults[0] as List<PeriodModel>;
        _userProfile = futureResults[1] as UserProfile?;
        _isPeriodActive = _checkIfPeriodIsActive();
      } else {
        rethrow;
      }
    }
  }
  
  
  bool _checkIfPeriodIsActive() {
    if (_periodRecords.isEmpty || _userProfile == null) {
      return false;
    }
    
    final today = DateTime.now();
    final normalizedToday = DateTime(today.year, today.month, today.day);
    
    
    final lastPeriodStart = _getLastPeriodStart();
    if (lastPeriodStart == null) {
      return false;
    }
    
    
    if (_hasEndRecordAfterStart(lastPeriodStart)) {
      return false;
    }
    
    
    return _isTodayInPeriodRange(normalizedToday, lastPeriodStart);
  }
  
  
  DateTime? _getLastPeriodStart() {
    final periodRecords = _periodRecords
        .where((r) => r.isPeriod)
        .toList()
        ..sort((a, b) => b.date.compareTo(a.date));
    
    return periodRecords.isNotEmpty ? periodRecords.first.date : null;
  }
  
  
  bool _hasEndRecordAfterStart(DateTime startDate) {
    final endRecords = _periodRecords
        .where((record) => !record.isPeriod)
        .toList()
        ..sort((a, b) => b.date.compareTo(a.date));
    
    if (endRecords.isEmpty) return false;
    
    final latestEndRecord = endRecords.first;
    return latestEndRecord.date.isAfter(startDate) || 
           latestEndRecord.date.isAtSameMomentAs(startDate);
  }
  
  
  bool _isTodayInPeriodRange(DateTime today, DateTime periodStart) {
    final expectedPeriodEnd = periodStart.add(Duration(days: _userProfile!.periodLength - 1));
    
    return !today.isBefore(periodStart) && !today.isAfter(expectedPeriodEnd);
  }
  
  
  Future<void> recordPeriodStart(DateTime date, {String? notes}) async {
    return _errorHandler.safeOperation(
      () async {
        
        final updatedRecord = await _getOrCreatePeriodRecord(date, true, notes: notes);
        
        
        await _dataService.savePeriodRecord(updatedRecord);
        
        
        await _updateLastPeriodDate(date);
        
        
        await _refreshCycleInfo();
        
        debugPrint('记录经期开始成功: ${date.toIso8601String()}');
      },
      'AppStateService.recordPeriodStart',
      rethrowError: true,
    );
  }
  
  
  Future<PeriodModel> _getOrCreatePeriodRecord(DateTime date, bool isPeriod, {String? notes}) async {
    
    final existingRecordIndex = _periodRecords.indexWhere(
      (r) => r.date.year == date.year && r.date.month == date.month && r.date.day == date.day
    );
    
    final updatedRecord = (existingRecordIndex != -1) 
      ? _periodRecords[existingRecordIndex].copyWith(isPeriod: isPeriod, notes: notes)
      : PeriodModel(
          date: date, 
          isPeriod: isPeriod, 
          isOvulation: false,
          isToday: date.year == DateTime.now().year && 
                   date.month == DateTime.now().month && 
                   date.day == DateTime.now().day,
          isPredictedPeriod: false,
          isPossiblePeriod: false,
          notes: notes);
    
    
    if (existingRecordIndex != -1) {
      _periodRecords[existingRecordIndex] = updatedRecord;
    } else {
      _periodRecords.add(updatedRecord);
    }
    
    return updatedRecord;
  }
  
  
  Future<void> _updateLastPeriodDate(DateTime date) async {
    if (_userProfile != null) {
      final updatedProfile = _userProfile!.copyWith(lastPeriodDate: date);
      _userProfile = updatedProfile;
      await _dataService.saveUserProfile(updatedProfile);
    }
  }
  
  
  Future<void> _refreshCycleInfo() async {
    try {
      final cycleInfo = await _periodService.getCycleInfo();
      _currentCycleInfo = cycleInfo;
    } catch (e) {
      debugPrint('刷新周期信息失败: $e');
      _currentCycleInfo = null;
    }
  }
  
  
  Future<void> recordPeriodEnd(DateTime date) async {
    return _errorHandler.safeOperation(
      () async {
        
        await _validatePeriodStartExists(date);
        
        
        final endRecord = await _getOrCreatePeriodRecord(date, false);
        await _dataService.savePeriodRecord(endRecord);
        
        
        await _refreshCycleInfo();
        
        debugPrint('记录经期结束成功: ${date.toIso8601String()}');
      },
      'AppStateService.recordPeriodEnd',
      rethrowError: true,
    );
  }
  
  
  Future<void> _validatePeriodStartExists(DateTime endDate) async {
    // 1. 首先检查内存中的记录
    final recentStartRecords = _periodRecords
        .where((record) => record.isPeriod)
        .where((record) => record.date.isBefore(endDate) || record.date.isAtSameMomentAs(endDate))
        .toList()
        ..sort((a, b) => b.date.compareTo(a.date));
    
    if (recentStartRecords.isNotEmpty) {
      return; // 内存中找到记录，验证通过
    }
    
    // 2. 内存中未找到记录，直接从数据库查询
    try {
      // 查询数据库中最近的经期开始记录
      final dbRecords = await _dataService.getRecentPeriodRecords(limit: 10);
      final dbStartRecords = dbRecords
          .where((record) => record.date.isBefore(endDate) || record.date.isAtSameMomentAs(endDate))
          .toList();
      
      if (dbStartRecords.isNotEmpty) {
        // 如果数据库中有记录，但内存中没有，更新内存缓存
        _periodRecords.addAll(dbStartRecords);
        return; // 数据库中找到记录，验证通过
      }
    } catch (e) {
      debugPrint('数据库查询失败: $e');
      // 查询失败时继续，最后才抛出异常
    }
    
    // 3. 内存和数据库中都未找到记录，抛出异常
    throw Exception('未找到对应的经期开始记录，请先记录经期开始');
  }
  
  
  Future<void> updatePeriodRecord(PeriodModel record) async {
    return _errorHandler.safeOperation(
      () async {
        
        final existingIndex = _periodRecords.indexWhere(
          (r) => r.date.year == record.date.year &&
                 r.date.month == record.date.month &&
                 r.date.day == record.date.day
        );
        
        if (existingIndex != -1) {
          _periodRecords[existingIndex] = record;
        } else {
          _periodRecords.add(record);
        }
        
        
        await _dataService.updatePeriodRecord(record);
        
        
        if (record.isPeriod) {
          
          if (record.date.isAfter(_userProfile!.lastPeriodDate)) {
            await _updateLastPeriodDate(record.date);
          }
          
          
          await _refreshCycleInfo();
        }
        
        debugPrint('更新经期记录成功: ${record.date}');
      },
      'AppStateService.updatePeriodRecord',
      rethrowError: true,
    );
  }

  
  Future<void> deletePeriodRecord(DateTime date) async {
    return _errorHandler.safeOperation(
      () async {
        
        _periodRecords.removeWhere(
          (r) => r.date.year == date.year &&
                 r.date.month == date.month &&
                 r.date.day == date.day
        );
        
        
        await _dataService.deletePeriodRecord(date);
        
        
        await _refreshCycleInfo();
        
        debugPrint('删除经期记录成功: $date');
      },
      'AppStateService.deletePeriodRecord',
      rethrowError: true,
    );
  }

  
  Future<void> deletePeriodRecords(List<DateTime> dates) async {
    try {
      
      for (final date in dates) {
        _periodRecords.removeWhere(
          (r) => r.date.year == date.year &&
                 r.date.month == date.month &&
                 r.date.day == date.day
        );
      }
      
      
      await _dataService.deletePeriodRecords(dates);
      
      
      _currentCycleInfo = await _periodService.getCycleInfo();
      
      debugPrint('批量删除经期记录成功: ${dates.length} 条');
    } catch (e) {
      debugPrint('Failed to delete period records: $e');
      throw Exception('批量删除经期记录失败: $e');
    }
  }
  
  
  Future<T> _safeOperation<T>(Future<T> Function() operation, String operationName, {bool rethrowError = false}) async {
    try {
      return await operation();
    } catch (e) {
      debugPrint('Failed to $operationName: $e');
      final errorMessage = '$operationName失败: $e';
      // 使用_errorHandler进行错误转换，保持一致性
      return _errorHandler.safeOperation(
        () async => throw Exception(errorMessage),
        operationName,
        rethrowError: rethrowError
      );
    }
  }

  
  Future<void> refresh() async {
    return _safeOperation<void>(
      () async {
        await _loadData();
        debugPrint('数据刷新成功');
      },
      '刷新数据',
      rethrowError: true,
    );
  }

  
  Future<List<Map<String, dynamic>>> getPredictions({String? type}) async {
    return _safeOperation<List<Map<String, dynamic>>>(
      () async => await _dataService.getValidPredictions(type: type),
      '获取预测结果',
      rethrowError: false,
    ).catchError((_) => <Map<String, dynamic>>[]); 

  }

  
  Future<List<Map<String, dynamic>>> getPredictionsByDateRange(DateTime startDate, DateTime endDate) async {
    return _safeOperation<List<Map<String, dynamic>>>(
      () async => await _dataService.getPredictionsByDateRange(startDate, endDate),
      '获取日期范围内的预测',
      rethrowError: false,
    ).catchError((_) => <Map<String, dynamic>>[]); 

  }

  
  Future<void> refreshPredictions() async {
    return _safeOperation<void>(
      () async {
        // 由于 DataService 中可能没有 refreshPredictions 方法，我们直接更新周期信息
        _currentCycleInfo = await _periodService.getCycleInfo();
        
        debugPrint('预测刷新成功');
      },
      '预测刷新',
      rethrowError: true,
    );
  }

  
  Future<bool> _isPredictionType(DateTime date, String predictionType) async {
    try {
      final predictions = await _dataService.getPredictionsByDateRange(date, date);
      return predictions.any((prediction) => prediction['type'] == predictionType);
    } catch (e) {
      debugPrint('检查预测类型 $predictionType 失败: $e');
      return false;
    }
  }

  
  Future<bool> isPredictedPeriod(DateTime date) async {
    return _isPredictionType(date, 'period');
  }

  
  Future<bool> isPredictedOvulation(DateTime date) async {
    return _isPredictionType(date, 'ovulation');
  }

  
  Future<bool> isFertilePeriod(DateTime date) async {
    return _isPredictionType(date, 'fertile');
  }
  
  
  Future<List<PeriodModel>> getMonthData(DateTime date) async {
    if (!_isInitialized) {
      await initializeApp();
    }
    
    
    final monthData = _periodRecords.where((record) => 
      record.date.year == date.year && 
      record.date.month == date.month
    ).toList();
    
    
    if (monthData.isEmpty) {
      try {
        await _loadData();
        return _periodRecords.where((record) => 
          record.date.year == date.year && 
          record.date.month == date.month
        ).toList();
      } catch (e) {
        debugPrint('Failed to load month data: $e');
        return [];
      }
    }
    
    return monthData;
  }
  
  
  
  void saveBasalTemperatureRecord(DateTime date, double temperature) {
    
    debugPrint('保存基础体温记录: $date, $temperature°C');
  }

  
  List<Map<String, dynamic>> getBasalTemperatureRecords(DateTime startDate, DateTime endDate) {
    
    
    return [
      {'date': startDate.add(const Duration(days: 1)), 'temperature': 36.2},
      {'date': startDate.add(const Duration(days: 2)), 'temperature': 36.3},
      {'date': startDate.add(const Duration(days: 3)), 'temperature': 36.4},
    ];
  }

  
  void saveOvulationTestRecord(DateTime date, String imagePath, int resultStrength, String interpretation) {
    
    debugPrint('保存排卵试纸测试记录: $date, 强度: $resultStrength, 解释: $interpretation');
  }

  
  List<Map<String, dynamic>> getOvulationTestRecords(int limit) {
    
    
    return [
      {
        'date': DateTime.now().subtract(const Duration(days: 1)),
        'imagePath': '',
        'resultStrength': 3,
        'interpretation': '强阳，24-36小时内即将排卵'
      },
      {
        'date': DateTime.now().subtract(const Duration(days: 2)),
        'imagePath': '',
        'resultStrength': 2,
        'interpretation': '弱阳，接近排卵期'
      },
    ];
  }

  
  double calculatePregnancyProbability() {
    
    return 35.0; 

  }

  
  String getFertilityAdvice() {
    
    return '今日受孕概率较高，建议安排同房。'; 

  }
  
  
  Future<List<Period>> getRecentCycles() async {
    return await _periodService.getRecentCycles();
  }
  
  
  Future<CycleInfo> getCycleInfo() async {
    return await _periodService.getCycleInfo();
  }
  
  
  Future<List<PeriodModel>> loadPeriodRecords() async {
    return await _dataService.loadPeriodRecords();
  }
  
  
  Future<void> updateUserProfile(UserProfile profile) async {
    return _errorHandler.safeOperation(
      () async {
        await _dataService.saveUserProfile(profile);
        _userProfile = profile;
        
        
        if (true) {
          _currentCycleInfo = await _periodService.getCycleInfo();
        }
        
        await refresh(); 

        debugPrint('用户档案更新成功');
      },
      'AppStateService.updateUserProfile',
      rethrowError: true,
    );
  }

  
  Future<void> updateCycleSettings(int cycleLength, int periodLength) async {    
    return _safeOperation<void>(
      () async {
        
        if (cycleLength < 21 || cycleLength > 45) {
          throw Exception('周期长度必须在21-45天之间');
        }
        if (periodLength < 1 || periodLength > 10) {
          throw Exception('经期长度必须在1-10天之间');
        }
        
        
        if (_userProfile != null) {
          final updatedProfile = _userProfile!.copyWith(
            cycleLength: cycleLength,
            periodLength: periodLength
          );
          await _dataService.saveUserProfile(updatedProfile);
          
          
          _userProfile = updatedProfile;
        }
        
        
        _currentCycleInfo = await _periodService.getCycleInfo();
        
        await refresh(); 

        debugPrint('周期设置更新成功');
      },
      '周期设置更新',
      rethrowError: true,
    );
  }

  
  Future<Map<String, int>> getCycleSettings() async {
    try {
      
      final settings = await _dataService.getCycleSettings();
      
      return {
        'cycleLength': settings['cycleLength'] as int,
        'periodLength': settings['periodLength'] as int,
      };
    } catch (e) {
      debugPrint('获取周期设置失败: $e');
      
      return {
        'cycleLength': _userProfile?.cycleLength ?? 28,
        'periodLength': _userProfile?.periodLength ?? 5,
      };
    }
  }

  
  Future<void> setLastPeriodDate(DateTime date) async {
    return _safeOperation<void>(
      () async {
        if (_userProfile != null) {
          final updatedProfile = _userProfile!.copyWith(lastPeriodDate: date);
          await _dataService.saveUserProfile(updatedProfile);
          _userProfile = updatedProfile;
          
          
          _currentCycleInfo = await _periodService.getCycleInfo();
          
          await refresh(); 

          debugPrint('上一次经期日期设置成功: $date');
        }
      },
      '设置上一次经期日期',
      rethrowError: true,
    );
  }
  
  
  UserProfile? get userProfile => _userProfile;
  
  
  bool get isMinimalistMode => _isMinimalistMode;
  
  
  Future<void> setMinimalistMode(bool enabled) async {
    return _safeOperation<void>(
      () async {
        _isMinimalistMode = enabled;
        
        final prefs = await SharedPreferences.getInstance();
        await prefs.setBool('isMinimalistMode', enabled);
        debugPrint('极简模式状态更新: $enabled');
      },
      '设置极简模式',
      rethrowError: true,
    );
  }
  
  
  Future<bool> checkDatabaseStructure() async {
    return _safeOperation<bool>(
      () async => await _dataService.checkDatabaseStructure(),
      '检查数据库结构',
      rethrowError: false,
    ).catchError((_) => false); 

  }
  
  
  Future<void> reinitializeDataService() async {
    return _safeOperation<void>(
      () async {
        await _dataService.reinitializeDatabase();
        await refresh();
        debugPrint('数据服务重新初始化成功');
      },
      '重新初始化数据服务',
      rethrowError: true,
    );
  }
}